package com.example.waterorder.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.waterorder.entity.Building;
import com.example.waterorder.entity.Order;
import com.example.waterorder.entity.User;
import com.example.waterorder.entity.constant.WaterConstant;
import com.example.waterorder.dto.BuildingOrder;
import com.example.waterorder.mapper.BuildingMapper;
import com.example.waterorder.mapper.OrderMapper;
import com.example.waterorder.mapper.UserMapper;
import com.example.waterorder.service.OrderService;
import com.example.waterorder.tools.DistanceUtils;
import com.example.waterorder.tools.UuidTool;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

@Service
public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements OrderService {
    @Resource
    private OrderMapper orderMapper;
    @Resource
    private UserMapper userMapper;
    @Resource
    private BuildingMapper buildingMapper;

    /**
     * 通过传入Order里的open_id(用户id)拿到用户注册时的buiding和dormi宿舍信息
     * 添加当前时间作为订单创建时间
     * 添加uuid设置的orderId
     * @param order
     * @return
     */
    @Override
    public Integer createOrder(Order order) {
        User user = userMapper.selectById(order.getUserId());
        if (order.getBuilding() == null ||order.getBuilding().isEmpty())
        {
            order.setBuilding(user.getBuilding());
        }
        if (order.getDormi() == null ||order.getDormi().isEmpty())
        {
            order.setDormi(user.getDormi());
        }

        Date nowtime = new Date();
        order.setTime(nowtime);
        order.setOrderId(UuidTool.getUUID32());
        int insert = orderMapper.insert(order);
        return insert;
    }

    @Override
    public Order selectOrderByOrderId(String orderId) {
        LambdaQueryWrapper<Order> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Order::getOrderId,orderId);
        return orderMapper.selectOne(queryWrapper);
    }

    @Override
    public List<Order> selectOrder(String building,Integer delivery) {
        LambdaQueryWrapper<Order> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Order::getBuilding,building)
                .eq(Order::getStateDelivery,delivery);
        return orderMapper.selectList(queryWrapper);
    }

    /**
     * 用户查看订单：通过用户id查询订单
     * delivery为空查询所有，delivery不为空查询对应状态的订单
     * @param userId
     * @param delivery
     * @return
     */
    @Override
    public List<Order> selectOrderByUserId(String userId,Integer delivery) {
        if(delivery==null)
        {
            LambdaQueryWrapper<Order> queryWrapper=new LambdaQueryWrapper<>();
            queryWrapper.eq(Order::getUserId,userId)
                    .orderBy(true,false,Order::getTime);
            return orderMapper.selectList(queryWrapper);
        }
        else{
            LambdaQueryWrapper<Order> queryWrapper=new LambdaQueryWrapper<>();
            queryWrapper.eq(Order::getUserId,userId)
                    .eq(Order::getStateDelivery,delivery);
            return orderMapper.selectList(queryWrapper);
        }
    }

    /**
     * 送水员查看订单
     * 都为空查询所有，任一不为空查询特定
     * @param building
     * @param delivery
     * @return
     */
    @Override
    public List<Order> selectOrderByWorker(String workerId,String building, Integer delivery) {
        LambdaQueryWrapper<Order> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Order::getWorkerId, workerId).orderBy(true,false,Order::getTime);
        if (building != null) {
            queryWrapper.eq(Order::getBuilding, building);
        }
        if (delivery != null) {
            queryWrapper.eq(Order::getStateDelivery, delivery);
        }
        return orderMapper.selectList(queryWrapper);
    }

    /**
     * 送水员查看今日的所有订单
     * @return
     */
    @Override
    public List<Order> selectOrderToday(String workerId,String delivery){
        QueryWrapper<Order> queryWrapper = new QueryWrapper<>();
        queryWrapper.apply(true, "TO_DAYS(NOW())-TO_DAYS(time) = 0")
                .eq("worker_id",workerId);
        if (delivery!=null&&!delivery.isEmpty())
        {
            queryWrapper.eq("state_delivery",delivery);
        }
        return orderMapper.selectList(queryWrapper);
    }

    /**
     * TODO 返回前端一个按宿舍楼分开的二级列表，使用DTO
     * @return
     */
    @Override
    public List<BuildingOrder> selectBuildingOrderNotAccept(String lng,String lat) {
        List<BuildingOrder> buildingOrderList = new ArrayList<>();
        List<Building> buildingList = buildingMapper.selectList(null);
        for (Building building : buildingList) {

            LambdaQueryWrapper<Order> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(Order::getBuilding,building.getName())
                    .eq(Order::getStateDelivery,0);
            List<Order> orderList = orderMapper.selectList(queryWrapper);
            if(orderList!=null && !orderList.isEmpty())
            {
                BuildingOrder buildingOrder = new BuildingOrder();
                buildingOrder.setBuilding(building.getName());
                buildingOrder.setOrder(orderList);

                Integer totalQuantity=0;
                for (Order order : orderList) {
                    totalQuantity+=order.getQuantity();
                }
                buildingOrder.setTotalQuantity(totalQuantity);

                if (building.getLng()!=null && building.getLat()!=null)
                {
                    Integer distance = DistanceUtils.getDistanceStr(lng,lat,
                            building.getLng(),building.getLat());
                    buildingOrder.setDistance(distance);
                }
                buildingOrderList.add(buildingOrder);
            }
        }
        return buildingOrderList;
    }

    @Override
    public List<BuildingOrder> selectBuildingOrderNotDelivery(String workerId,String lng,String lat) {
        List<BuildingOrder> buildingOrderList = new ArrayList<>();
        List<Building> buildingList = buildingMapper.selectList(null);
        for (Building building : buildingList) {

            LambdaQueryWrapper<Order> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(Order::getBuilding,building.getName())
                    .eq(Order::getStateDelivery,1)
                    .eq(Order::getWorkerId,workerId);
            List<Order> orderList = orderMapper.selectList(queryWrapper);
            if(orderList!=null && !orderList.isEmpty())
            {
                BuildingOrder buildingOrder = new BuildingOrder();
                buildingOrder.setBuilding(building.getName());
                buildingOrder.setOrder(orderList);

                Integer totalQuantity=0;
                for (Order order : orderList) {
                    totalQuantity+=order.getQuantity();
                }
                buildingOrder.setTotalQuantity(totalQuantity);

                if (building.getLng()!=null && building.getLat()!=null)
                {
                    Integer distance = DistanceUtils.getDistanceStr(lng,lat,
                            building.getLng(),building.getLat());
                    buildingOrder.setDistance(distance);
                }
                buildingOrderList.add(buildingOrder);
            }
        }
        return buildingOrderList;
    }

    /**
     * 送水员查看水桶数
     * 都为空查询所有，任一不为空查询特定
     * @param building
     * @param delivery
     * @return
     */
    @Override
    public Integer selectQuantity(String workerId, String building, Integer delivery) {
        QueryWrapper<Order> queryWrapper = new QueryWrapper<>();
        queryWrapper.select("sum(quantity) as sumQuantity")
                .eq("worker_id", workerId);

        if (building != null) {
            queryWrapper.eq("building", building);
        }

        if (delivery != null) {
            queryWrapper.eq("state_delivery", delivery);
        }

        List<Map<String, Object>> maxMap = orderMapper.selectMaps(queryWrapper);
        if (maxMap == null || maxMap.isEmpty() || maxMap.get(0) == null) {
            return 0;
        } else {
            BigDecimal bigDecimal = (BigDecimal) maxMap.get(0).get("sumQuantity");
            return bigDecimal != null ? bigDecimal.intValue() : 0;
        }
    }


    /**
     * 查询今日售出且送达桶数
     * @return
     */
    @Override
    public Integer selectQuantityToday(String workerId) {
        QueryWrapper<Order> queryWrapper = new QueryWrapper<>();
        queryWrapper.select("sum(quantity) as sumQuantity")
                .apply(true, "TO_DAYS(NOW())-TO_DAYS(time) = 0")
                .eq("state_delivery",WaterConstant.ORDER_DELIVERY_STATE)
                .eq("worker_id",workerId);

        List<Map<String, Object>> maxMap = orderMapper.selectMaps(queryWrapper);
        if(maxMap.get(0)==null||maxMap==null)
        {
            return 0;
        }
        else {
            BigDecimal bigDecimal= (BigDecimal) maxMap.get(0).get("sumQuantity");
            return Integer.parseInt(bigDecimal.toString());
        }
    }

    /**
     * 送水员查看今日营业额(已送达)
     * @return
     */
    @Override
    public Double selectTodayAmount(String workerId) {
        QueryWrapper<Order> queryWrapper = new QueryWrapper<>();
        queryWrapper.select("sum(quantity) as sumQuantity")
                .apply(true, "TO_DAYS(NOW())-TO_DAYS(time) = 0")
                .eq("state_delivery",WaterConstant.ORDER_DELIVERY_STATE)
                .eq("worker_id",workerId);
        List<Map<String, Object>> maxMap = orderMapper.selectMaps(queryWrapper);

        if(maxMap.get(0)==null||maxMap==null)
        {
            return 0.0;
        }
        else {
            BigDecimal bigDecimal = (BigDecimal) maxMap.get(0).get("sumQuantity");
            Integer totalquantity = Integer.parseInt(bigDecimal.toString());
            Double totalAmount = totalquantity* WaterConstant.WATER_PRICE;
            return totalAmount;
        }
    }

    @Override
    public Double selectWeeklyAmount(String workerId) {

        Integer weeklyOrderQuantity = orderMapper.getWeeklyOrderQuantity(workerId);
        Double weeklyAmount = weeklyOrderQuantity*WaterConstant.WATER_PRICE;
        return weeklyAmount;
    }

    @Override
    public Double selectMonthlyAmount(String workerId) {
        Integer monthlyOrderQuantity = orderMapper.getMonthlyOrderQuantity(workerId);
        Double MonthlyAmount = monthlyOrderQuantity*WaterConstant.WATER_PRICE;
        return MonthlyAmount;
    }

    /**
     * 送水员查看总营业额(已送达)
     * @return
     */
    @Override
    public Double selectTotalAmount(String workerId) {
        QueryWrapper<Order> queryWrapper = new QueryWrapper<>();
        queryWrapper.select("sum(quantity) as sumQuantity")
                .eq("state_delivery",WaterConstant.ORDER_DELIVERY_STATE)
                .eq("worker_id",workerId);
        List<Map<String, Object>> maxMap = orderMapper.selectMaps(queryWrapper);

        if(maxMap.get(0)==null||maxMap==null)
        {
            return 0.0;
        }
        else {
            BigDecimal bigDecimal = (BigDecimal) maxMap.get(0).get("sumQuantity");
            Integer totalquantity = Integer.parseInt(bigDecimal.toString());
            Double totalAmount = totalquantity* WaterConstant.WATER_PRICE;
            return totalAmount;
        }
    }

    @Override
    public Integer updateOrder(Order order) {
        int updateById = orderMapper.updateById(order);
        return updateById;
    }

}
